package org.shijiagen.search.listener;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.xcontent.XContentType;
import org.shijiagen.clients.ProductClient;
import org.shijiagen.doc.ProductDoc;
import org.shijiagen.pojo.Product;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@RequiredArgsConstructor
public class SpringBootListener implements ApplicationRunner {

    private final RestHighLevelClient restHighLevelClient;

    private final ProductClient productClient;
    private final static String PRODUCT_STRUCT = """
            {
              "mappings": {
                "properties": {
                  "productId":{
                    "type": "integer"
                  },
                  "productName":{
                    "type": "text",
                    "analyzer": "ik_smart",
                    "copy_to": "all"
                  },
                  "categoryId":{
                    "type": "integer"
                  },
                  "productTitle":{
                    "type": "text",
                    "analyzer": "ik_smart",
                    "copy_to": "all"
                  },
                  "productIntro":{
                    "type":"text",
                    "analyzer": "ik_smart",
                    "copy_to": "all"
                  },
                  "productPicture":{
                    "type": "keyword",
                    "index": false
                  },
                  "productPrice":{
                    "type": "double",
                    "index": true
                  },
                  "productSellingPrice":{
                    "type": "double"
                  },
                  "productNum":{
                    "type": "integer"
                  },
                  "productSales":{
                    "type": "integer"
                  },
                  "all":{
                    "type": "text",
                    "analyzer": "ik_max_word"
                  }
                }
              }
            }
            """;

    /**
     * springboot项目启动后则会执行该方法
     * 在此方法中进行es的初始化操作
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 判断es中是否存在product索引
        boolean exists = restHighLevelClient.indices().exists(new GetIndexRequest("product"), RequestOptions.DEFAULT);
        if (exists) {
            // 如果索引存在则删除原有数据
            restHighLevelClient.deleteByQuery(new DeleteByQueryRequest("product").setQuery(QueryBuilders.matchAllQuery()), RequestOptions.DEFAULT);
        }else {
            // 如果索引不存在则创建索引
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("product");
            createIndexRequest.source(PRODUCT_STRUCT, XContentType.JSON);
            restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        }
        // 查询所有商品数据
        List<Product> productsList = productClient.allList();
        // 将数据批量插入es
        BulkRequest bulkRequest = new BulkRequest();
        // 新建一个json转换对象
        ObjectMapper objectMapper = new ObjectMapper();
        productsList.stream().parallel().forEach(product -> {
            // 创建插入操作对象
            IndexRequest indexRequest = new IndexRequest("product").id(product.getProductId().toString());
            try {
                // 把商品对象转成JSON后写入es索引
                indexRequest.source(objectMapper.writer().writeValueAsString(new ProductDoc(product)), XContentType.JSON);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
            // 将该索引加到批量操作中
            bulkRequest.add(indexRequest);
        });
        // 执行批量操作
        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    }
}
